#pragma once

#include <string>
#include <vector>
#include <memory>
#include <unordered_map>
#include <functional>
#include "viml/vm.h"
#include "viml/debugger.h"
#include "viml/debug_info.h"

namespace viml {

/**
 * CLI调试命令类型
 */
enum class DebugCommandType {
    UNKNOWN,
    HELP,
    QUIT,
    CONTINUE,
    STEP,
    STEP_INTO,
    STEP_OVER,
    STEP_OUT,
    BREAKPOINT,
    BREAK,
    CLEAR,
    DELETE,
    LIST,
    INFO,
    BACKTRACE,
    WHERE,
    PRINT,
    LOCALS,
    GLOBALS,
    FRAME,
    UP,
    DOWN,
    DISASSEMBLE,
    RUN,
    FINISH,
    CONDITION,
    IGNORE,
    ENABLE,
    DISABLE
};

/**
 * CLI调试命令结构
 */
struct DebugCommand {
    DebugCommandType type;
    std::string name;
    std::vector<std::string> args;
    std::string help_text;

    DebugCommand(DebugCommandType t = DebugCommandType::UNKNOWN,
               const std::string& n = "",
               const std::vector<std::string>& a = {},
               const std::string& help = "")
        : type(t), name(n), args(a), help_text(help) {}
};

/**
 * 调试历史记录
 */
class DebugHistory {
private:
    std::vector<std::string> history;
    size_t current_index;
    static const size_t MAX_HISTORY = 100;

public:
    DebugHistory();
    void add(const std::string& command);
    std::string get_previous();
    std::string get_next();
    std::string get_current() const;
    void reset();
    std::vector<std::string> get_all() const;
};

/**
 * 命令自动补全器
 */
class CommandCompleter {
private:
    std::vector<std::string> commands;
    std::unordered_map<std::string, std::vector<std::string>> command_args;

public:
    CommandCompleter();
    void initialize();
    std::vector<std::string> complete(const std::string& partial, size_t cursor_pos);
    void add_command(const std::string& name, const std::vector<std::string>& args = {});
};

/**
 * CLI调试界面显示格式化器
 */
class DebugDisplay {
private:
    std::shared_ptr<Debugger> debugger;
    std::shared_ptr<DebugInfo> debug_info;

    // 显示配置
    bool show_instructions;
    bool show_registers_flag;
    bool show_stack_trace;
    int source_context_lines;

public:
    DebugDisplay(std::shared_ptr<Debugger> dbg, std::shared_ptr<DebugInfo> info);

    // 配置方法
    void set_show_instructions(bool show) { show_instructions = show; }
    void set_show_registers(bool show) { show_registers_flag = show; }
    void set_show_stack_trace(bool show) { show_stack_trace = show; }
    void set_source_context_lines(int lines) { source_context_lines = lines; }

    // 显示方法
    void show_current_location();
    void show_breakpoints();
    void show_call_stack();
    void show_locals();
    void show_globals();
    void show_registers();
    void show_source_context();
    void show_disassembly(size_t start_pc = 0, size_t count = 10);
    void show_help(const std::string& command = "");
    void show_welcome();
    void show_goodbye();
    void show_info(const std::string& info);
    void show_error(const std::string& error);

private:
    // 帮助显示方法
    void show_general_help();
    void show_command_help(const std::string& command);

public:
    // 格式化辅助方法
    std::string format_value(const Value& value);
    std::string format_source_line(int line, const std::string& prefix = "");
    std::string format_frame_info(size_t frame_index);
};

/**
 * CLI调试器主类
 *
 * 提供交互式调试界面，支持：
 * - 命令解析和执行
 * - 历史记录和自动补全
 * - 调试信息显示
 * - 断点管理
 * - 单步执行控制
 * - 变量检查
 */
class DebuggerCLI {
private:
    std::shared_ptr<Debugger> debugger;
    std::shared_ptr<DebugInfo> debug_info;
    std::shared_ptr<VM> vm;
    std::unique_ptr<DebugDisplay> display;
    std::unique_ptr<DebugHistory> history;
    std::unique_ptr<CommandCompleter> completer;

    // 运行状态
    bool is_running;
    bool should_quit;
    bool should_execute_program_flag = false;
    bool should_step_execute = false;
    std::string current_file;

    // 命令注册表
    std::unordered_map<std::string, DebugCommand> command_registry;
    std::unordered_map<std::string, std::string> command_aliases;

    // 核心方法
    void initialize_commands();
    void register_command(const DebugCommand& command);
    void register_alias(const std::string& alias, const std::string& command);

    // 命令解析和执行
    DebugCommand parse_command(const std::string& input);
    void execute_command(const DebugCommand& command);
    bool validate_command(const DebugCommand& command);

    // 命令实现
    void cmd_help(const std::vector<std::string>& args);
    void cmd_quit(const std::vector<std::string>& args);
    void cmd_continue(const std::vector<std::string>& args);
    void cmd_step(const std::vector<std::string>& args);
    void cmd_step_into(const std::vector<std::string>& args);
    void cmd_step_over(const std::vector<std::string>& args);
    void cmd_step_out(const std::vector<std::string>& args);
    void cmd_breakpoint(const std::vector<std::string>& args);
    void cmd_break(const std::vector<std::string>& args);
    void cmd_clear(const std::vector<std::string>& args);
    void cmd_delete(const std::vector<std::string>& args);
    void cmd_list(const std::vector<std::string>& args);
    void cmd_info(const std::vector<std::string>& args);
    void cmd_backtrace(const std::vector<std::string>& args);
    void cmd_where(const std::vector<std::string>& args);
    void cmd_print(const std::vector<std::string>& args);
    void cmd_locals(const std::vector<std::string>& args);
    void cmd_globals(const std::vector<std::string>& args);
    void cmd_frame(const std::vector<std::string>& args);
    void cmd_up(const std::vector<std::string>& args);
    void cmd_down(const std::vector<std::string>& args);
    void cmd_disassemble(const std::vector<std::string>& args);
    void cmd_run(const std::vector<std::string>& args);
    void cmd_finish(const std::vector<std::string>& args);
    void cmd_condition(const std::vector<std::string>& args);
    void cmd_ignore(const std::vector<std::string>& args);
    void cmd_enable(const std::vector<std::string>& args);
    void cmd_disable(const std::vector<std::string>& args);

    // 断点解析辅助方法
    int parse_line_number(const std::string& line_str);
    std::string parse_condition_expression(const std::vector<std::string>& args, size_t start_idx);
    std::string extract_function_name_from_context(const std::string& location);

    // 调试状态管理
    void start_debugger();
    void stop_debugger();
    void pause_debugger();
    void resume_debugger();
    void update_debugger_state();

    // 用户交互
    std::string read_command_line();
    std::vector<std::string> complete_command(const std::string& partial);
    void handle_command_completion();

public:
    DebuggerCLI(std::shared_ptr<VM> virtual_machine,
                std::shared_ptr<Debugger> dbg = nullptr,
                std::shared_ptr<DebugInfo> info = nullptr);

    ~DebuggerCLI() = default;

    // 禁用拷贝构造和赋值
    DebuggerCLI(const DebuggerCLI&) = delete;
    DebuggerCLI& operator=(const DebuggerCLI&) = delete;

    // 主要接口
    bool load_file(const std::string& filename);
    int run_interactive();
    int run_single_command(const std::string& command);

    // 配置方法
    void set_debugger(std::shared_ptr<Debugger> dbg);
    void set_debug_info(std::shared_ptr<DebugInfo> info);
    void configure_display(bool show_instructions = false, bool show_registers = false, bool show_stack_trace = true, int source_context = 5);

    // 信息显示方法
    void show_info(const std::string& info);
    void show_error(const std::string& error);

    // 状态查询
    bool is_debugger_active() const { return debugger && debugger->is_active(); }
    bool should_exit() const { return should_quit; }
    const std::string& get_current_file() const { return current_file; }

    // 程序执行控制
    bool should_execute_program() const { return should_execute_program_flag; }
    void set_should_execute_program(bool flag) { should_execute_program_flag = flag; }
    bool should_step_execute_program() const { return should_step_execute; }
    void set_should_step_execute(bool flag) { should_step_execute = flag; }
};

/**
 * CLI调试器工厂函数
 */
std::unique_ptr<DebuggerCLI> create_debugger_cli(std::shared_ptr<VM> vm);

} // namespace viml